package com.syh.jn.scm.service.impl.upstream.finance;

import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.event.annotation.DomainEventHandle;
import com.syh.core.ddd.infrastructure.repository.AggregateRepository;
import com.syh.core.ddd.service.AbstractServiceImpl;
import com.syh.jn.scm.domain.upstream.entity.finance.UpReceiptBill;
import com.syh.jn.scm.domain.upstream.entity.finance.UpSalesInvoice;
import com.syh.jn.scm.domain.upstream.entity.finance.UpSalesInvoiceEvent;
import com.syh.jn.scm.domain.upstream.entity.finance.UpStatementAccountBill;
import com.syh.jn.scm.domain.upstream.event.UpReceiptBillEvent;
import com.syh.jn.scm.domain.upstream.event.UpStatementAccountBillEvent;
import com.syh.jn.scm.domain.upstream.repository.finance.UpStatementAccountBillRepository;
import com.syh.jn.scm.dto.support.FilesDto;
import com.syh.jn.scm.dto.upstream.finance.UpStatementAccountBillItemVo;
import com.syh.jn.scm.dto.upstream.finance.UpStatementAccountBillMto;
import com.syh.jn.scm.dto.upstream.finance.UpStatementAccountBillSto;
import com.syh.jn.scm.dto.upstream.finance.UpStatementAccountBillVo;
import com.syh.jn.scm.service.api.upstream.finance.UpStatementAccountBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class UpStatementAccountBillServiceImpl extends AbstractServiceImpl<UpStatementAccountBillSto, UpStatementAccountBillMto, UpStatementAccountBillVo, UpStatementAccountBill, Long> implements UpStatementAccountBillService {
  @Autowired
  private UpStatementAccountBillRepository upStatementAccountBillRepositoryImpl;

  @Override
  protected AggregateRepository<UpStatementAccountBill, Long> getAggregateRepository() {
    return upStatementAccountBillRepositoryImpl;
  }


  /**
   * 业务确认
   *
   * @param id
   */
  @Override
  public void businessConfirmation(Long id) {
    UpStatementAccountBill bill = upStatementAccountBillRepositoryImpl.getById(id);
    bill.businessConfirmation();
    upStatementAccountBillRepositoryImpl.update(bill);
  }

  /**
   * 业务取消确认
   *
   * @param id
   */
  @Override
  public void businessCancelConfirmation(Long id) {
    UpStatementAccountBill bill = upStatementAccountBillRepositoryImpl.getById(id);
    bill.businessCancelConfirmation();
    upStatementAccountBillRepositoryImpl.update(bill);
  }

  /**
   * 财务确认
   *
   * @param id
   */
  @Override
  public void financeConfirmation(Long id) {
    UpStatementAccountBill bill = upStatementAccountBillRepositoryImpl.getById(id);
    bill.financeConfirmation();
    upStatementAccountBillRepositoryImpl.update(bill);
  }

  /**
   * 财务取消确认
   *
   * @param id
   */
  @Override
  public void financeCancelConfirmation(Long id) {
    UpStatementAccountBill bill = upStatementAccountBillRepositoryImpl.getById(id);
    bill.financeCancelConfirmation();
    upStatementAccountBillRepositoryImpl.update(bill);
  }

  /**
   * 生成对账单
   *
   * @param sto
   * @return
   */
  @Override
  public Long save(UpStatementAccountBillSto sto) {
    UpStatementAccountBill bill = new UpStatementAccountBill(sto);
    Long id = upStatementAccountBillRepositoryImpl.add(bill);
    bill.setId(id);
    this.publicEvent(UpStatementAccountBillEvent.bulidUpStatementBillAccountCreated(new Object[]{bill}));
    return id;
  }

  /**
   * 修改对账单
   * @param mto
   */
  @Override
  public void update(UpStatementAccountBillMto mto) {
    UpStatementAccountBill bill = upStatementAccountBillRepositoryImpl.getById(mto.getId());
    bill.modify(mto);
    upStatementAccountBillRepositoryImpl.update(bill);
    this.publicEvent(UpStatementAccountBillEvent.bulidUpStatementBillAccountUpdata(new Object[]{bill}));
  }

  /**
   * 删除对账单
   *
   * @param id
   */
  @Override
  public void delete(Long id) {
    UpStatementAccountBill bill = upStatementAccountBillRepositoryImpl.getById(id);
    bill.destroy();
    this.publicEvent(UpStatementAccountBillEvent.bulidUpStatementBillAccountDestory(new Object[]{bill}));
    //删除
    upStatementAccountBillRepositoryImpl.remove(bill);
  }

  /**
   * 上传单据图片
   *
   * @param dto
   */
  @Override
  public void upload(FilesDto dto) {
    UpStatementAccountBill bill = upStatementAccountBillRepositoryImpl.getById(dto.getId());
    bill.upload(dto);
    upStatementAccountBillRepositoryImpl.upload(bill);
  }

  /**
   * 根据对账单id获取明细
   *
   * @param statementId 对账单id
   * @return
   */
  @Override
  public List<UpStatementAccountBillItemVo> getItemsByStatementId(Long statementId) {
    return upStatementAccountBillRepositoryImpl.getItemsByStatementId(statementId);
  }

  /**
   * 消费者：监听付款单（修改收款到账金额）
   *
   * @param bill
   */
  @DomainEventHandle(UpReceiptBillEvent.UP_RECEIPT_BILL_LOCK)
  protected void handleUpStatementBillAccountRecEvent(UpReceiptBill bill) {
    UpStatementAccountBill billState = upStatementAccountBillRepositoryImpl.getById(bill.getStatementOfAccountId());
    billState.accountAmount(bill.getPrice());
    upStatementAccountBillRepositoryImpl.update(billState);
  }

  /**
   * 消费者：监听付款单（取消到账,到账金额还原,状态还原）
   *
   * @param bill
   */
  @DomainEventHandle(UpReceiptBillEvent.UP_RECEIPT_BILL_UNLOCK)
  protected void handleUpStatementBillAccountRecCancelEvent(UpReceiptBill bill) {
    UpStatementAccountBill billState = upStatementAccountBillRepositoryImpl.getById(bill.getStatementOfAccountId());
    billState.subAccountAmount(bill.getPrice());
    upStatementAccountBillRepositoryImpl.update(billState);
  }

  /**
   * 消费者：监听进项发票创建（修改对账单已生成开票金额）
   *
   * @param salesInvoice
   */
  @DomainEventHandle(UpSalesInvoiceEvent.UP_SALES_INVOICE_CREATED)
  protected void handleUpStatementBillAccountSalesInvoiceCreatedEvent(UpSalesInvoice salesInvoice) {
    UpStatementAccountBill billState = upStatementAccountBillRepositoryImpl.getById(salesInvoice.getStatementOfAccountId());
    billState.addGeneratedTicketPrice(salesInvoice.getPrice());
    upStatementAccountBillRepositoryImpl.update(billState);
  }

  /**
   * 消费者：监听进项发票删除（修改对账单已生成开票金额）
   *
   * @param salesInvoice
   */
  @DomainEventHandle(UpSalesInvoiceEvent.UP_SALES_INVOICE_DESTROY)
  protected void handleUpStatementBillAccountSalesInvoiceDestoryEvent(UpSalesInvoice salesInvoice) {
    UpStatementAccountBill billState = upStatementAccountBillRepositoryImpl.getById(salesInvoice.getStatementOfAccountId());
    billState.subGeneratedTicketPrice(salesInvoice.getPrice());
    upStatementAccountBillRepositoryImpl.update(billState);
  }

  /**
   * 消费者：监听开票（修改开票金额）
   * @param bill
   */
  //TODO 暂时放在服务端监听
/*  @DomainEventHandle(UpStatementAccountBillEvent.UP_STATEMENT_BILL_INVOICE_DESTORY)
  protected void handleUpStatementBillInvoiceEvent(UpStatementAccountBill bill) {
    UpStatementAccountBill billState = upStatementAccountBillRepositoryImpl.getById(bill.getId());
    billState.invoiceValue(bill.getTicketPrice());
    upStatementAccountBillRepositoryImpl.update(billState);
  }*/


}
